package Queue;

import Command.SetCommand;

import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicStampedReference;

public  class CircleQueue {
    // true为可以写入 false为不可以写入
    private  AtomicInteger WriteFlag;
    private  AtomicInteger ReadFlag;
    AtomicStampedReference<Boolean> WriteCAS = new AtomicStampedReference(true, 0);
    AtomicStampedReference<Boolean> ReadCAS = new AtomicStampedReference(true, 0);


    SetCommand[] setCommands;
    volatile int head;
    volatile int tail;
    volatile int size;
    volatile boolean sameCycle;


    public CircleQueue(){
         setCommands = new SetCommand[2000] ;
         head = 0;
         size = 2000;
         sameCycle = true;
    }

    public int push(SetCommand setCommand){

        while(true){
            if(isFull()){
                return -1;
            }
            if(  WriteCAS.compareAndSet(true,false,WriteCAS.getStamp(),WriteCAS.getStamp()+1)){
                break;
            }
        }
        setCommands[tail] = setCommand;
        tail = (tail+1)%size;
        if(tail == 0) {
            sameCycle = false;
        }
        WriteCAS.compareAndSet(false,true,WriteCAS.getStamp(),WriteCAS.getStamp()+1);
        return  1;

    }

    public SetCommand pop(){

        while(true){
         //   System.out.println("isEmpty");
            if(isEmpty()){

                return null;
            }
            if(ReadCAS.compareAndSet(true,false,ReadCAS.getStamp(),ReadCAS.getStamp()+1)  ){
                break;
            }
        }
        SetCommand res =     setCommands[head];
        head = (head+1)%size;
        if(head == 0){
            sameCycle = true;
        }
        ReadCAS.compareAndSet(false,true,ReadCAS.getStamp(),ReadCAS.getStamp()+1);
        return res;
    }

    public boolean isFull(){

        return head == tail && !sameCycle;

    }

    public boolean isEmpty(){

        return  head == tail && sameCycle;
    }



}
